﻿using System;
using System.Xml.Linq;
using System.Linq;
using Silent.API.LastFm.Model;

namespace Silent.API.LastFm
{
    public static class Converter
    {
        public static Artist ConvertToArtist(XElement element)
        {
            if (element == null)
                return null;

            var artist = new Artist();
            var name = element.Element("name");
            if (name != null)
                artist.Name = name.Value;
            var mbid = element.Element("mbid");
            if (mbid != null)
                artist.Mbid = mbid.Value;
            var url = element.Element("url");
            if (url != null)
                artist.LastFmUrl = url.Value;
            artist.Images = element.Descendants("image").Select(ConvertToImage).ToArray();
            var similar = element.Element("similar");
            if (similar != null)
                artist.Similar = similar.Descendants("artist").Select(ConvertToArtist).ToArray();
            artist.Stats = ConvertToStats(element.Element("stats"));
            artist.Tags = element.Descendants("tag").Select(ConvetToTag).ToArray();
            artist.Bio = ConvertToWiki(element.Element("bio"));
            var streamable = element.Element("streamable");
            if (streamable != null)
                artist.Streamable = Convert.ToBoolean(int.Parse(streamable.Value));
            var ontour = element.Element("ontour");
            if (ontour != null)
                artist.OnTour = Convert.ToBoolean(int.Parse(ontour.Value));
            return artist;
        }
        public static Image ConvertToImage(XElement element)
        {
            if (element == null)
                return null;

            var image = new Image
                {
                    Size = element.Attribute("size").Value,
                    Url = element.Value
                };
            return image;
        }
        public static Stats ConvertToStats(XElement element)
        {
            if (element == null)
                return null;

            var stats = new Stats();
            var listeners = element.Element("listeners");
            if (listeners != null)
                stats.Listeners = long.Parse(listeners.Value);
            var plays = element.Element("playcount");
            if (plays != null)
                stats.Plays = long.Parse(plays.Value);
            return stats;
        }
        public static Tag ConvetToTag(XElement element)
        {
            if (element == null)
                return null;

            var tag = new Tag();
            var name = element.Element("name");
            if (name != null)
                tag.Name = name.Value;
            var url = element.Element("url");
            if (url != null)
                tag.LastFmUrl = url.Value;
            return tag;
        }
        public static Wiki ConvertToWiki(XElement element)
        {
            if (element == null)
                return null;

            var bio = new Wiki();
            var published = element.Element("published");
            if (published != null)
                bio.Published = DateTime.Parse(published.Value);
            var summary = element.Element("summary");
            if (summary != null)
                bio.Summary = summary.Value;
            var content = element.Element("content");
            if (content != null)
                bio.Content = content.Value;
            var yearformed = element.Element("yearformed");
            if (yearformed != null)
                bio.YearFormed = int.Parse(yearformed.Value);
            return bio;
        }

        public static Album ConvertToAlbum(XElement element)
        {
            if (element == null)
                return null;

            var album = new Album();
            var name = element.Element("name");
            if (name != null)
                album.Name = name.Value;
            var artist = element.Element("artist");
            if (artist != null)
                album.Artist = artist.Value;
            var id = element.Element("id");
            if (id != null)
                album.AlbumId = long.Parse(id.Value);
            var mbid = element.Element("mbid");
            if (mbid != null)
                album.Mbid = mbid.Value;
            var url = element.Element("url");
            if (url != null)
                album.LastFmUrl = url.Value;
            var releasedate = element.Element("releasedate");
            if (releasedate != null)
                album.ReleaseDate = DateTime.Parse(releasedate.Value);
            album.Images = element.Descendants("image").Select(ConvertToImage).ToArray();
            album.Stats = ConvertToStats(element);
            album.Tracks = element.Descendants("tracks").Select(ConvertToTrack).ToArray();
            album.Tags = element.Descendants("tag").Select(ConvetToTag).ToArray();
            album.Wiki = ConvertToWiki(element.Element("wiki"));
            return album;
        }
        public static Track ConvertToTrack(XElement element)
        {
            if (element == null)
                return null;

            var track = new Track();
            var name = element.Element("name");
            if (name != null)
                track.Name = name.Value;
            var mbid = element.Element("mbid");
            if (mbid != null)
                track.Mbid = mbid.Value;
            var duration = element.Element("duration");
            if (duration != null)
                track.Duration = int.Parse(duration.Value);
            var url = element.Element("url");
            if (url != null)
                track.LastFmUrl = url.Value;
            var streamable = element.Element("streamable");
            if (streamable != null)
                track.Streamable = Convert.ToBoolean(int.Parse(streamable.Value));
            track.Album = ConvertToAlbum(element.Element("album"));
            track.Artist = ConvertToArtist(element.Element("artist"));
            track.Tags = element.Descendants("tag").Select(ConvetToTag).ToArray();
            track.Wiki = ConvertToWiki(element.Element("wiki"));
            return track;
        }
        public static NowPlaying ConvertToNowPlaying(XElement element)
        {
            var nowplaying = new NowPlaying
                {
                    Track = ConvertToMetadata(element.Element("track")),
                    Artist = ConvertToMetadata(element.Element("artist")),
                    Album = ConvertToMetadata(element.Element("album")),
                    IgnoreMessage = ConvertToError(element.Element("ignoredMessage"))
                };
            return nowplaying;
        }
        public static Correction ConvertToMetadata(XElement element)
        {
            var metadata = new Correction
                {
                    Corrected = Convert.ToBoolean(int.Parse(element.Attribute("corrected").Value)),
                    Name = element.Value
                };
            return metadata;
        }

        public static Session ConvertToSession(XElement element)
        {
            if(element == null)
                return null;

            var session = new Session();
            var name = element.Element("name");
            if (name != null)
                session.Name = name.Value;
            var key = element.Element("key");
            if (key != null)
                session.SessionKey = key.Value;
            var subscriber = element.Element("subscriber");
            if (subscriber != null)
                session.Subscriber = Convert.ToBoolean(int.Parse(subscriber.Value));
            return session;
        }

        public static RequestError ConvertToError(XElement element)
        {
            var error = new RequestError
                {
                    Code = int.Parse(element.Attribute("code").Value),
                    Message = element.Value
                };
            return error;
        }
    }
}